<template>
  <div class="page">
    <h2>药品目录权限控制</h2>
    <div class="controls">
      <el-input v-model="roleQuery" placeholder="搜索角色" size="small" clearable style="width:220px" />
      <el-button size="small" @click="newRole">新建角色</el-button>
      <el-button size="small" @click="copyRole">复制角色</el-button>
      <el-button size="small" @click="deleteRole">删除角色</el-button>
      <el-button size="small" @click="exportJSON">导出JSON</el-button>
      <el-button size="small" @click="openImport">导入JSON</el-button>
      <input ref="importFileRef" type="file" accept="application/json" style="display:none" @change="handleImport" />
    </div>

    <div class="layout">
      <div class="panel left">
        <h3>角色</h3>
        <div class="roles" v-if="filteredRoles.length">
          <div class="role-item" v-for="r in filteredRoles" :key="r.id" :class="{active: r.id===selectedRoleId}">
            <div>
              <strong>{{ r.name }}</strong>
              <div class="muted">ID:{{ r.id }} • {{ r.perms.length }} 权限</div>
            </div>
            <div>
              <el-button size="small" @click="selectRole(r.id)">选择</el-button>
            </div>
          </div>
        </div>
        <div v-else class="muted">暂无角色</div>

        <div style="margin-top:10px">
          <el-input v-model="roleName" placeholder="角色名称" size="small" />
          <div style="margin-top:8px;text-align:right">
            <el-button size="small" type="primary" @click="saveRole">保存角色</el-button>
          </div>
        </div>
        <div class="hint">提示：角色决定用户对药品目录的操作权限（查看/编辑/删除/导入/导出/权限管理）</div>
      </div>

      <div class="panel right">
        <h3 style="margin-top:-5px">权限矩阵</h3>
        <div class="muted">勾选赋予角色对应权限。改变后请点击“保存角色”。</div>
        <el-table :data="perms" style="width:100%;margin-top:8px" border>
          <el-table-column prop="name" label="权限项" />
          <el-table-column prop="desc" label="说明" />
          <el-table-column label="允许" width="140">
            <template #default="{ row }">
              <div style="text-align:center">
                <el-checkbox v-model="selectedPerms" :label="row.id" />
              </div>
            </template>
          </el-table-column>
        </el-table>

        <h3 style="margin-top:14px">用户分配</h3>
        <div style="display:flex;gap:8px;align-items:center;margin-bottom:8px">
          <el-input v-model="userQuery" placeholder="搜索用户" size="small" clearable style="flex:1" />
          <el-button size="small" type="primary" @click="assignSelectedUsers">分配选中用户到当前角色</el-button>
        </div>
        <div class="user-list">
          <div v-if="filteredUsers.length">
            <div class="user-item" v-for="u in filteredUsers" :key="u.id">
              <div>
                <strong>{{ u.name }}</strong> <span class="muted">({{ u.account }})</span>
                <div class="muted" style="margin-top:6px">
                  <template v-if="(u.roles || []).length">
                    <el-tag v-for="rid in u.roles" :key="rid" type="info" size="small" style="margin-right:6px">{{ roleNameById(rid) }}</el-tag>
                  </template>
                  <template v-else>
                    <span class="muted">未分配角色</span>
                  </template>
                </div>
              </div>
              <div style="display:flex;flex-direction:column;gap:6px">
                <el-checkbox v-model="selectedUserIds" :label="u.id">选中</el-checkbox>
                <el-button size="mini" @click="viewUser(u.id)">查看权限</el-button>
              </div>
            </div>
          </div>
          <div v-else class="muted">暂无用户</div>
        </div>
        <div class="hint">示例用户均为假数据；可修改用户所属角色以查看“用户有效权限”</div>

        <h3 style="margin-top:14px">选中用户的有效权限（预览）</h3>
        <div id="effectivePerm" class="muted">{{ effectiveText }}</div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';

const KEY = 'demo_drug_permissions_v1';
const USER_KEY = 'demo_drug_users_v1';

const DEFAULT_PERMS = [
  {id:'view', name:'查看药品', desc:'能够查看药品目录列表和详情'},
  {id:'edit', name:'新增/编辑药品', desc:'可以新增或修改药品信息'},
  {id:'delete', name:'删除药品', desc:'可以删除药品记录'},
  {id:'import', name:'导入', desc:'从文件导入药品数据'},
  {id:'export', name:'导出', desc:'导出药品目录为文件'}
];

const DEFAULT_ROLES = [
  {id:1,name:'管理员', perms:['view','edit','delete','import','export','manage-perm']},
  {id:2,name:'处方科', perms:['view','edit','export']},
  {id:3,name:'门诊', perms:['view']}
];

const DEFAULT_USERS = [
  {id:101, account:'zhangsan', name:'张三', roles:[1]},
  {id:102, account:'lisi', name:'李四', roles:[2]},

];

function load(key, def){ try{ const raw = localStorage.getItem(key); if(!raw){ localStorage.setItem(key, JSON.stringify(def)); return JSON.parse(JSON.stringify(def)); } return JSON.parse(raw); }catch(e){ localStorage.setItem(key, JSON.stringify(def)); return JSON.parse(JSON.stringify(def)); } }
function save(key, v){ localStorage.setItem(key, JSON.stringify(v)); }

const perms = ref(DEFAULT_PERMS);
const roles = ref(load(KEY, DEFAULT_ROLES));
const users = ref(load(USER_KEY, DEFAULT_USERS));

const roleQuery = ref('');
const userQuery = ref('');
const selectedRoleId = ref(roles.value.length?roles.value[0].id:null);
const roleName = ref('');
const selectedPerms = ref([]);
const selectedUserIds = ref([]);
const selectedUserIdForView = ref(null);
const importFileRef = ref(null);

onMounted(()=>{ if(selectedRoleId.value) loadRoleToForm(selectedRoleId.value); });

const filteredRoles = computed(()=>{ const q = roleQuery.value.trim().toLowerCase(); return roles.value.filter(r=>!q || r.name.toLowerCase().includes(q)); });
const filteredUsers = computed(()=>{ const q = userQuery.value.trim().toLowerCase(); return users.value.filter(u=>!q || u.name.toLowerCase().includes(q) || u.account.toLowerCase().includes(q)); });

function loadRoleToForm(id){ const r = roles.value.find(x=>x.id===id); if(r){ roleName.value = r.name; selectedPerms.value = [...(r.perms||[])]; selectedRoleId.value = id; } else { roleName.value = ''; selectedPerms.value = []; selectedRoleId.value = null; } }

function selectRole(id){ loadRoleToForm(id); }
function newRole(){ selectedRoleId.value = null; roleName.value=''; selectedPerms.value = []; }

function saveRole(){ const name = roleName.value.trim(); if(!name){ ElMessage.warning('请输入角色名称'); return; } if(selectedRoleId.value){ const r = roles.value.find(x=>x.id===selectedRoleId.value); if(r){ r.name = name; r.perms = [...selectedPerms.value]; } } else { const nid = (roles.value.reduce((s,i)=>Math.max(s,i.id),0) || 0) + 1; roles.value.push({id:nid,name,perms:[...selectedPerms.value]}); selectedRoleId.value = nid; }
  save(KEY, roles.value); ElMessage.success('保存成功（保存在 localStorage）'); }

function deleteRole(){ if(!selectedRoleId.value){ ElMessage.warning('请选择要删除的角色'); return; } ElMessageBox.confirm('确认删除角色？将从所有用户中移除此角色','提示',{confirmButtonText:'确定',cancelButtonText:'取消',type:'warning'}).then(()=>{
    const rid = selectedRoleId.value; roles.value = roles.value.filter(r=>r.id!==rid); users.value.forEach(u=>{ u.roles = (u.roles||[]).filter(r=>r!==rid); }); save(KEY, roles.value); save(USER_KEY, users.value); selectedRoleId.value = roles.value.length?roles.value[0].id:null; loadRoleToForm(selectedRoleId.value); ElMessage.success('删除完成');
  }).catch(()=>{});
}

function copyRole(){ if(!selectedRoleId.value){ ElMessage.warning('请选择一个角色以复制'); return; } const r = roles.value.find(x=>x.id===selectedRoleId.value); const nid = (roles.value.reduce((s,i)=>Math.max(s,i.id),0) || 0) + 1; const nr = {id:nid,name:r.name+' - 复制', perms: [...r.perms]}; roles.value.push(nr); save(KEY, roles.value); selectedRoleId.value = nid; loadRoleToForm(nid); ElMessage.success('复制完成'); }

function exportJSON(){ const payload = { roles: roles.value, users: users.value, perms: perms.value }; const blob = new Blob([JSON.stringify(payload, null, 2)],{type:'application/json'}); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'drug_permissions_export.json'; document.body.appendChild(a); a.click(); a.remove(); URL.revokeObjectURL(url); ElMessage.success('已开始下载'); }

function openImport(){ if(importFileRef.value) importFileRef.value.click(); }

function handleImport(e){ const f = e.target.files[0]; if(!f) return; const reader = new FileReader(); reader.onload = ev=>{ try{ const obj = JSON.parse(ev.target.result); if(obj.roles) roles.value = obj.roles; if(obj.users) users.value = obj.users; save(KEY, roles.value); save(USER_KEY, users.value); ElMessage.success('导入成功'); }catch(err){ ElMessage.error('导入失败：文件格式错误') } }; reader.readAsText(f); e.target.value=''; }

function assignSelectedUsers(){ if(!selectedRoleId.value){ ElMessage.warning('请选择一个角色'); return; } const ids = selectedUserIds.value.slice(); if(ids.length===0){ ElMessage.warning('请选择至少一个用户'); return; } users.value.forEach(u=>{ if(ids.includes(u.id)){ u.roles = u.roles || []; if(!u.roles.includes(selectedRoleId.value)) u.roles.push(selectedRoleId.value); } }); save(USER_KEY, users.value); ElMessage.success('分配完成'); }

function viewUser(id){ selectedUserIdForView.value = id; const u = users.value.find(x=>x.id===id); if(!u) return; const eff = computeEffectivePerms(u); effectiveText.value = eff.length? eff.map(pid=>{ const p = perms.value.find(pp=>pp.id===pid); return p? p.name : pid; }).join(' , ') : '无任何权限'; }

function computeEffectivePerms(user){ const rids = user.roles||[]; const s = new Set(); rids.forEach(rid=>{ const rr = roles.value.find(x=>x.id===rid); if(rr && rr.perms) rr.perms.forEach(p=>s.add(p)); }); return Array.from(s); }

function roleNameById(rid){ const rr = roles.value.find(x=>x.id===rid); return rr? rr.name : '' }

const effectiveText = ref('请选择一个用户（点击查看权限）');
</script>

<style scoped>
.page{font-family: Arial, "Microsoft YaHei", sans-serif; margin:10px}
h2{margin-top:-10px}
.layout{display:flex;gap:16px;align-items:flex-start}
.panel{background:#fff;border:1px solid #e5e5e5;padding:12px;border-radius:4px;max-height:none}
.left{width:260px}
.right{flex:1}
.role-item{padding:8px;border-bottom:1px solid #f0f0f0;display:flex;justify-content:space-between;align-items:center}
.role-item.active{background:#f6fbff}
.small{font-size:13px;padding:6px 8px}
/* table styles remain but primary table is el-table */
th,td{border:1px solid #eee;padding:8px;text-align:left}
th{background:#fafafa}
.muted{color:#888}
.controls{display:flex;gap:8px;align-items:center;margin-bottom:8px}
.user-list{max-height:none;overflow:visible;border:1px solid #f0f0f0}
.user-item{padding:6px;border-bottom:1px solid #f7f7f7;display:flex;justify-content:space-between}
.tag{background:#f0f5ff;color:#225; padding:2px 6px;border-radius:3px;font-size:12px}
.hint{font-size:12px;color:#999;margin-top:2px}
</style>